package com.yfbao.horizon.schedule.tk.meter;

import com.yfbao.horizon.schedule.tk.conf.MyConditionalOnProperty;
import io.lettuce.core.event.DefaultEventBus;
import io.lettuce.core.event.Event;
import io.lettuce.core.event.EventBus;
import io.lettuce.core.event.command.CommandFailedEvent;
import io.lettuce.core.event.command.CommandStartedEvent;
import io.lettuce.core.event.command.CommandSucceededEvent;
import io.lettuce.core.event.connection.ConnectedEvent;
import io.lettuce.core.event.connection.DisconnectedEvent;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.support.ConnectionPoolSupport;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.time.Duration;

@Slf4j
@Configuration
@Conditional(MyConditionalOnProperty.class)
public class RedisLettueConfigMetrics {

//    @Bean(destroyMethod = "shutdown")
//    public ClientResources clientResources() {
//        // 启用命令延迟收集器
//        return ClientResources.builder()
//                .commandLatencyCollectorOptions(
//                        DefaultCommandLatencyCollectorOptions.builder()
//                                .enable()  // 启用延迟收集
//                                .build())
//                .build();
//    }



    @Bean(destroyMethod = "shutdown")
    public ClientResources clientResources(MeterRegistry meterRegistry) {
        // 创建一个 Scheduler 实例
        Scheduler scheduler = Schedulers.single();
        // 创建 DefaultEventBus 实例，传入 EventBusListener
        DefaultEventBus eventBusNew = new DefaultEventBus(scheduler);
        // 注册事件总线
        ClientResources clientResources = ClientResources.builder()
                .eventBus(eventBusNew)
                .build();

        // 订阅事件总线，监听 Redis 事件
        EventBus eventBus = clientResources.eventBus();
        subscribeToEvents(eventBus, meterRegistry);

        return clientResources;
    }

    private void subscribeToEvents(EventBus eventBus, MeterRegistry meterRegistry) {
        Flux<Event> events = eventBus.get();

        // 订阅连接事件
        events.subscribe(event -> {
            if (event instanceof ConnectedEvent) {
                System.out.println("Redis 连接已建立: " + event);
                meterRegistry.counter("redis.connection.events", "status", "connected").increment();
            } else if (event instanceof DisconnectedEvent) {
                System.out.println("Redis 连接已断开: " + event);
                meterRegistry.counter("redis.connection.events", "status", "disconnected").increment();
            }
        });

        // 订阅命令事件
        events.subscribe(event -> {
            if (event instanceof CommandStartedEvent) {
                System.out.println("Redis 命令开始执行: " + event);
            } else if (event instanceof CommandSucceededEvent) {
                CommandSucceededEvent succeededEvent = (CommandSucceededEvent) event;
                Duration duration = succeededEvent.getDuration();
                System.out.println("Redis 命令执行成功: " + event + ", 耗时: " + duration.toMillis() + "ms");

                // 记录命令执行时间
                meterRegistry.timer("redis.command.duration", "status", "success")
                        .record(duration);
            } else if (event instanceof CommandFailedEvent) {
                System.out.println("Redis 命令执行失败: " + event);
                meterRegistry.counter("redis.command.failures").increment();
            }
        });
    }
//    @Bean
//    @ConditionalOnBean(MyConditionalOnProperty.class)
//    public GenericObjectPool<?> redisConnectionPool(LettuceConnectionFactory lettuceConnectionFactory, MeterRegistry meterRegistry) {
//        GenericObjectPool<?> pool = ConnectionPoolSupport.createGenericObjectPool(lettuceConnectionFactory::getConnection,
//                new GenericObjectPoolConfig<>());
//
//        // 将连接池的相关信息暴露给 Micrometer
//        meterRegistry.gauge("redis.connection.pool.size", pool, GenericObjectPool::getNumActive);
//        meterRegistry.gauge("redis.connection.pool.idle", pool, GenericObjectPool::getNumIdle);
//        meterRegistry.gauge("redis.connection.pool.max", pool, GenericObjectPool::getMaxTotal);
//
//        return pool;
//    }
}
